package com.zyf.chapter02.behavior.strategy;

import java.util.HashMap;
import java.util.Map;

/**
 * 策略的创建
 * @author yifeng
 */
public class StrategyFactory {
    /**
     * {@link StrategyFactory_Stateful} 的优化版本，通过反射创建新对象
     * 但是该方法不能限定 Map 中存储的 Class 类型
     */
    private static final Map<String, Class> strategys = new HashMap<>();

    static {
        strategys.put("A", ConcreteStrategyA.class);
        strategys.put("B", ConcreteStrategyB.class);
    }

    public static Strategy getStrategy(String type) {

        Class<Strategy> clazz = strategys.get(type);
        try {
            return clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 无状态的策略类使用方式
     * 策略类不包含成员变量
     */
    public static class StrategyFactory_nonState {
        private static final Map<String, Strategy> strategys = new HashMap<>();
        static {
            strategys.put("A", new ConcreteStrategyA());
            strategys.put("B", new ConcreteStrategyB());
        }

        public static Strategy getStrategy(String type) {
            if (type == null || type.isEmpty()) {
                throw new IllegalArgumentException("type should not be empty");
            }
            return strategys.get(type);
        }
    }

    /**
     * 有状态的策略类
     * 每次调用 getStrategy 时都创建一个新的策略类
     */
    public static class StrategyFactory_Stateful {
        private static final Map<String, Strategy> strategys = new HashMap<>();

        public static Strategy getStrategy(String type) {
            if (type == null || type.isEmpty()) {
                throw new IllegalArgumentException("type should not be empty");
            }
            if (type.equals("A")) {
                return new ConcreteStrategyA();
            } else if (type.equals("B")) {
                return new ConcreteStrategyB();
            }
            return null;
        }
    }
}
